#pragma once

#include "imgui/imgui.h"

namespace Imgui 
{

struct TableLayout : public Window
{
	std::vector<Window> rows;
	std::vector<int> columnWidth;
};

namespace Layouts
{
	class LayoutBase
	{
	public:
		LayoutBase(Ui::UiState* p) : m_pUi(p) {}
		virtual ~LayoutBase() {}

		virtual void Begin(const Window& window, uint32 flags);
		virtual void AddItem(uint32 flags, Window* pWindow) = 0;
		virtual void End();

		int GetWidth() const;
		int GetHeight() const;
		Window& GetWindow() {return m_window;}
		uint32 GetFlags() const {return m_flags;}
		int GetLayoutCounter() const {return m_layoutCounter;}

	protected:
		Ui::UiState* m_pUi;
		Window m_window;
		int m_separation;
		int m_border;
		uint32 m_flags;
		int m_layoutCounter;
	};

	class FixedWindow : public LayoutBase
	{
	public:
		FixedWindow(Ui::UiState* p) : LayoutBase(p) {}

		void Begin(const Window& window, uint32 flags) override;
		void AddItem(uint32 flags, Window* pWindow) override;
	};

	class VerticalList : public LayoutBase
	{
	public:
		VerticalList(Ui::UiState* p) : LayoutBase(p) {}

		void Begin(const Window& window, uint32 flags) override;
		void AddItem(uint32 flags, Window* pWindow) override;
		void End() override;

		int Top() const {return m_top + m_window.offsetY;}

	private:
		int m_top;
		int m_bottom;
		int m_maxWidth;
	};

	class HorizontalList : public LayoutBase
	{
	public:
		HorizontalList(Ui::UiState* p) : LayoutBase(p) {}

		void Begin(const Window& window, uint32 flags) override;
		void AddItem(uint32 flags, Window* pWindow) override;
		void End() override;

	private:
		int m_left;
		int m_right;
		int m_maxHeight;
		int m_offset;
	};

	class Table : public LayoutBase
	{
	public:
		Table(Ui::UiState* p) : LayoutBase(p) {}

		void Begin(const Window& window, uint32 flags) override;
		void AddItem(uint32 flags, Window* pWindow) override;
		void End() override;

		void SetTableLayout(TableLayout* pLayout) {m_pLayout = pLayout;}

	private:
		TableLayout* m_pLayout;
		TableLayout m_layout;

		int m_top;
		int m_left;
	};

}

	struct Input
	{
		Input() : mouseL(false), mouseR(false), clickL(false), clickR(false), mouseX(0), mouseY(0), key(0) {}

		bool mouseL;
		bool mouseR;
		bool clickL;
		bool clickR;
		int mouseX, mouseY;
		char key;
	};

	struct Ui::UiState
	{
		UiState() : pressed(-1), hot(-1), previousHot(-1) {}

		std::list<Layouts::LayoutBase*> layoutStack;
		std::vector<int> levels;
		std::vector<Render::Rect> clipRectStack;
		std::map<int, Window> layoutWindows;
		std::map<int, TableLayout> layoutTables;

		int layoutCounter;
		int hotCounter;
		int pressedCounter;
		int pressed;
		int hot;
		int previousHot;
		int hotFloat;
		Input currentInput;
		Input previousInput;
		int row;
		int column;

		LayoutStyle style;

		void UpdateHot(uint32 hotFloat_);
		void PushClipRect(const Window& window);
		void PopClipRect();
		void OnKeyDown(uint16 unicode);

		enum class LayoutType
		{
			FIXED_WINDOW,
			HORIZONTAL_LIST,
			VERTICAL_LIST,
			TABLE,
		};

		void BeginLayout(LayoutType layout, uint32 flags, const Window* pWindow = 0);
		void EndLayout(Window* pWindow = 0);
	};

}